package com.ys.utils.base.j2se;

import com.alibaba.fastjson.JSON;
import com.google.gson.*;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ 名称:json 工具类
 * @ 创建人: dhf
 * @ 参数： null
 * @ 创建时间: 2022/5/10
 * @ 修改人和其它信息
 * @ 返回值:
 */
public class JsonUtil {
    public static GsonBuilder gb = new GsonBuilder().registerTypeAdapter(Date.class, new DateAdapter()).registerTypeAdapter(Timestamp.class,new TimestampAdapter());
    public static Gson gson = gb.serializeNulls().create();

    public static Gson gsonNull  = new GsonBuilder().registerTypeAdapterFactory(new NullStringToEmptyAdapterFactory()).create();

    /**
     * json字符串转换成泛型对象
     * @param json
     * @param objClass  最后得到的对象
     * @param clazz     泛型对象
     * @param <T>
     * @return
     */
    @SuppressWarnings("rawtypes")
	public static  <T> T fromJson(String json, Class objClass,Class clazz) {
        Type objectType = type(objClass, clazz);
        return gson.fromJson(json, objectType);
    }
    /**
     * 泛型对象组装
     * @param raw
     * @param args
     * @return
     */
    @SuppressWarnings("rawtypes")
	static ParameterizedType type(final Class raw, final Type... args) {
        return new ParameterizedType() {
            public Type getRawType() {
                return raw;
            }
            public Type[] getActualTypeArguments() {
                return args;
            }
            public Type getOwnerType() {
                return null;
            }
        };
    }

    /**
     * 将对象转化为json串
     * @param object 对象
     * @return json串
     */
    public static String toJson(Object object){
        return gson.toJson(object);
    }

    /**
     * 对象 转 Map
     */
    public static Map<String,Object> beanToMap(Object object){
        return JSON.parseObject(toJson(object)).getInnerMap();
    }

    /**
     * 对象集合 转 List<Map>
     */
    public static List<Map<String,Object>> beanToList(List<?> list){
        return list.stream().map(x->JSON.parseObject(toJson(x)).getInnerMap()).collect(Collectors.toList());
    }

    /**
     * JSON 转 对象
     */
    public static <T> T jsonToBean(String str, Class<T> type) {
        return gson.fromJson(str, type);
    }
    public static <T> T jsonNullToBean(String str, Class<T> type) {
        return gsonNull.fromJson(str, type);
    }
    /**
     * Map 转 对象
     */
    public static <T> T mapToBean(Map map, Class<T> clazz) {
        return jsonToBean(toJson(map),clazz);
    }

    static class TimestampAdapter implements JsonSerializer<Timestamp>, JsonDeserializer<Timestamp>{
        @Override
        public Timestamp deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            if(json == null){
                return null;
            } else {
                try {
                    return new Timestamp(json.getAsLong());
                } catch (Exception e) {
                    return null;
                }
            }
        }

        @Override
        public JsonElement serialize(Timestamp src, Type typeOfSrc, JsonSerializationContext context) {
            String value = "";
            if(src != null){
                value = String.valueOf(src.getTime());
            }
            return new JsonPrimitive(value);
        }
    }

    static class DateAdapter implements JsonSerializer<Date>, JsonDeserializer<Date>{
        @Override
        public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            if(json == null){
                return null;
            } else {
                try {
                    return new Date(json.getAsLong());
                } catch (Exception e) {
                    return null;
                }
            }
        }

        @Override
        public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
            String value = "";
            if(src != null){
                value = String.valueOf(src.getTime());
            }
            return new JsonPrimitive(value);
        }
    }
}